#ifndef _MODEL_H_
#define _MODEL_H_

#include "render.h"
#include "quater.h"
#include <vector>
#include <string>
#include <map>

using namespace std;

struct mdl_vertex
{
	vector3 m_pos;
	vector3 m_normal;
	vector2 m_tex;
};

struct mdl_triangle
{
	u32     m_vertexes[3];
	vector3 m_normals[3];
	vector2 m_texcoords[3];
};

struct mdl_material
{
	mdl_material(){m_texture=0;}
	~mdl_material(){if(m_texture){delete m_texture;}}

	material m_material;
	texture* m_texture;
};

struct mdl_mesh
{
	int  m_material_id;
	u32  m_first_pr;
	u32  m_pr_count;
	bool m_indexed;

	vector3 m_min;
	vector3 m_max;
};

struct mdl_keyframe
{
	float   m_time;
	vector3 m_position;
	quater  m_rotate;
};

class mdl_track
{
public:
	mdl_track(){m_frames.clear();}
	~mdl_track(){m_frames.clear();}

	matrix4 get_transform(float _time);

	u32					 m_boneid;
	vector<mdl_keyframe> m_frames;
};

class mdl_animation
{
public:
	mdl_animation(){m_traks.clear();}
	~mdl_animation(){m_traks.clear();}

	mdl_track* get_track(u32 _boneid);

	vector<mdl_track> m_traks;
	float			  m_length;
};

struct mdl_weight
{
	u32   m_bone;
	u32   m_vertex;
	float m_value;
};

struct mdl_bone
{
	mdl_bone(){m_parent=-1;}
	matrix4	   	 m_matrix;
	u32		     m_parent;
};

class model
{
public:
	model();
	~model();
	void load(const char* _fname);
	void load_ms3d(const char* _fname);
	void load_ogrexml(const char*_fname);
	void load_ogreani(const char*_fname);
	void release();
	void draw_static();
	void draw_anim();
	void draw_subset(const char* _name);
	void draw_subset(string _name);
	void draw_shader(effect* _fx,const char* _tex_param=0,const char* _col_param=0);
	float set_anim(const char* _name);
	void  set_time(float _time);

	mdl_mesh* get_subset(const char* _name);
	mdl_mesh* get_subset(string _name);

	vector3 get_min(){return m_min;}
	vector3 get_max(){return m_max;}

private:

	vector3 m_min;
	vector3 m_max;

	render*		  m_render;
	vbuffer*	  m_vbuffer;
	ibuffer*      m_ibuffer;

	vector<mdl_vertex>    m_vertexes;
	vector<mdl_vertex>    m_animvtxs;
	vector<mdl_mesh>	  m_meshes;
	vector<mdl_material>  m_materials;

	vector<mdl_weight>		  m_weights;
	vector<mdl_bone>		  m_bones;
	map<string,mdl_animation> m_animations;
	mdl_bone*				  m_boneroot;
	mdl_animation*			  m_currani;

	map<string,mdl_mesh*> m_subsetes;
};

#endif